/*
* 事件管理器
* */
define(['browser'], function(browser){
	/**
	 * 构造函数
	 * @param {object} object 需要绑定Eventer功能的对象
	 */
	function Eventer(object) {

		if (!this instanceof Eventer) {
			return new Eventer(object);
		}

		if (typeof object !== 'object' || object instanceof Eventer || object.__events__ || object.on || object.off || object.trigger) {
			throw new TypeError('Unable to bind object to Eventer.');
			return false;
		}

		this.__object   = object;
		object.__events__ = {};
		object.on       = this.__on;
		object.off      = this.__off;
		object.trigger = object.emit = this.__trigger;

	}

	/**
	 * 用于获取传入的对象
	 * @return {object} 返回绑定事件模块之后的对象
	 */
	Eventer.prototype.getObject = function() {
		return this.__object;
	};

	/**
	 * 用来订阅事件，可单个或者多个
	 * @param  {string | object} eventName 事件名，订阅单个事件时为一个字符串，订阅多个事件则需要传入一个包含事件名/函数的键值对
	 * @param  {function} method 事件函数，仅订阅单个事件时才需要
	 * @return {object} 返回自身以便于链式调用
	 */
	Eventer.prototype.__on = function(eventName, method) {

		var __event;

		if (typeof eventName === "object") {

			for (__event in eventName) {
				if (Object.prototype.hasOwnProperty.call(eventName, __event) && (typeof eventName[__event] === "function")) {
					this.on(__event, eventName[__event]);
				}
			}

		} else if (typeof eventName === "string" && typeof method === "function") {

			this.__events__[eventName] || (this.__events__[eventName] = []);
			this.__events__[eventName].push(method);

		}

		return this;

	};

	/**
	 * 删除一个指定的事件队列
	 * @param  {string} eventName 需要删除的事件名
	 * @return {object} 返回自身以便于链式调用
	 */
	Eventer.prototype.__off = function(eventName, method) {

		if (typeof eventName === 'string') {
			var events = this.__events__;
			var eventsArray = events[ eventName ];

			if ( eventsArray !== undefined ) {
				if(typeof method === 'function'){
					var index = eventsArray.indexOf( method );
					if ( index !== - 1 ) {
						eventsArray.splice( index, 1 );
					}
				}else{
					this.__events__[eventName] = [];
				}
			}
		}

		return this;
	};

	/**
	 * 用于发布一个指定的事件
	 * @param {string | ...any} 传入的第一个参数为需要发布的事件明，其后的参数会传递给事件队列中的每个函数
	 * @return {object} 返回自身以便于链式调用
	 */
	Eventer.prototype.__trigger = function() {

		var __eventName = Array.prototype.shift.call(arguments),
			__arguments = arguments,
			__returnFalse = false,
			__that = this,
			__return;

		if (typeof __eventName === 'string' && Object.prototype.hasOwnProperty.call(this.__events__, __eventName) && (this.__events__[__eventName] instanceof Array)) {

			for(var i = 0, method; i < this.__events__[__eventName].length; i++){
				method = this.__events__[__eventName][i];
				if (!__returnFalse) {
					__return = method.apply(__that, __arguments);
					__return === false && (__returnFalse = true);
				}
			}

		}

		return this;

	};

	//事件类型兼容
	Eventer.events = (function(){
		var mouseEvents = browser.versions.mobile ?
			{
				down : 'touchstart',
				move : 'touchmove',
				up : 'touchend',
				click : 'touchend',
				over : 'touchstart',
				out : 'touchend',
				cancel : 'touchcancel'
			}
			:
			{
				down : 'mousedown',
				move : 'mousemove',
				up : 'mouseup',
				click : 'click',
				over : 'mouseover',
				out : 'mouseout',
				cancel : 'mouseout'
			};
		return mouseEvents;
	})();

	//获取触摸事件对象
	Eventer.getTouchEvent = function(e){
		if(browser.versions.mobile){
			e = e.originalEvent.targetTouches[0];
		}

		return e;
	};

	return Eventer;
});